package com.igoal.web;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.tuckey.web.filters.urlrewrite.utils.StringUtils;

import com.igoal.dto.GoalDTO;
import com.igoal.dto.UserDTO;
import com.igoal.dto.UserGoalDTO;
import com.igoal.dto.UserGoalPhaseDTO;
import com.igoal.service.GoalEntryManager;
import com.igoal.service.GoalManager;
import com.igoal.service.MessageManager;
import com.igoal.service.UserGoalManager;
import com.igoal.service.UserManagerExt;
import com.igoal.utils.ConvertUtils;
import com.igoal.web.model.BaseModel;
import com.igoal.web.model.SMARTGoalModel;
import com.igoal.web.model.UserDashboardModel;

@Controller
public class SMARTGoalController extends BaseController {
	private final static Log logger = LogFactory.getLog(SMARTGoalController.class);
	
	@Autowired
	public void setUserManagerExt(UserManagerExt userManagerExt) {
		this.userManagerExt = userManagerExt;
	}

	@Autowired
	public void setGoalManager(GoalManager goalManager) {
		this.goalManager = goalManager;
	}

	@Autowired
	public void setMessageManager(MessageManager messageManager) {
		this.messageManager = messageManager;
	}

	@Autowired
	public void setUserGoalManager(UserGoalManager userGoalManager) {
		this.userGoalManager = userGoalManager;
	}

	@Autowired
	public void setGoalEntryManager(GoalEntryManager goalEnryManager) {
		this.goalEntryManager = goalEnryManager;
	}
	
	public String getViewPrefix() {
		return BaseControllerDelegate.DEFAULT_VIEW_PREFIX;
	}
	
	@RequestMapping(method=RequestMethod.GET, value="/manageSMARTGoal.html")
	public String showManageSMARTGoalForm(ModelMap modelMap, HttpServletRequest request, @RequestParam(required=false, value="goalId") Long goalId){
		if(goalId == null || goalId <= 0L){
			return "redirect:/dashboard.html";
		}
		
		SMARTGoalModel model = new SMARTGoalModel();
		
		initTopPage(model, request);
		initRightPage(model, request);
		initManageSMARTGoal(goalId, model, request);
		
		applyModel(modelMap, model);
		
		return getViewPrefix() + "manageSMARTGoal";
	}	
	
	@RequestMapping(method=RequestMethod.POST, value="/manageSMARTGoal.html")
	public String updateTasks(@ModelAttribute("data") SMARTGoalModel data, HttpServletRequest request){
		List<UserGoalPhaseDTO> phases = new ArrayList<UserGoalPhaseDTO>();
		if(isValidPhase(data.getPhase1())){
			phases.add(data.getPhase1());
		}
		if(isValidPhase(data.getPhase2())){
			phases.add(data.getPhase2());
		}
		if(isValidPhase(data.getPhase3())){
			phases.add(data.getPhase3());
		}
		if(isValidPhase(data.getPhase4())){
			phases.add(data.getPhase4());
		}
		if(isValidPhase(data.getPhase5())){
			phases.add(data.getPhase5());
		}
		if(isValidPhase(data.getPhase6())){
			phases.add(data.getPhase6());
		}
		if(isValidPhase(data.getPhase7())){
			phases.add(data.getPhase7());
		}
		if(isValidPhase(data.getPhase8())){
			phases.add(data.getPhase8());
		}
		if(isValidPhase(data.getPhase9())){
			phases.add(data.getPhase9());
		}
		if(isValidPhase(data.getPhase10())){
			phases.add(data.getPhase10());
		}
		
		String userSession = getUserInSession();
		
		userGoalManager.updatePhases(userSession, phases);
		
		return "redirect:manageSMARTGoal.html?goalId="+data.getUserGoal().getGoalId();
	}
	
//	@RequestMapping(method=RequestMethod.GET, value="/addShouldDoGoal.html")
//	public String addSMARTGoalById(@RequestParam("goalId") Long goalId){
//		return "redirect:/addSMARTGoal.html";
//	}
	
	@RequestMapping(method=RequestMethod.POST, value="/addNewSMARTGoal.html")
	public String addGoalTitleToRequest(@ModelAttribute("data") UserDashboardModel data, HttpServletRequest request){		
		String title = data.getNewGoalTitle();
		request.getSession().setAttribute("goalTitleAttr", title);
		return "redirect:/addSMARTGoal.html";
	}
	
	@RequestMapping(method=RequestMethod.GET, value="/addSMARTGoal.html")
	public String showAddSMARTGoalForm(ModelMap modelMap, HttpServletRequest request){
		SMARTGoalModel model = new SMARTGoalModel();
		
		initTopPage(model, request);
		initRightPage(model, request);
		initLeftPage(model, request);
		
		applyModel(modelMap, model);
		
		return getViewPrefix() + "addSMARTGoal";
	}
	
	@RequestMapping(method=RequestMethod.POST, value="/addSMARTGoal.html")
	public String submitSMARTGoalForm(@ModelAttribute("data") SMARTGoalModel data, BindingResult bindingResult, HttpServletRequest request){
		if(data != null){
			List<UserGoalPhaseDTO> phases = new ArrayList<UserGoalPhaseDTO>();
			if(isValidPhase(data.getPhase1())){
				phases.add(data.getPhase1());
			}
			if(isValidPhase(data.getPhase2())){
				phases.add(data.getPhase2());
			}
			if(isValidPhase(data.getPhase3())){
				phases.add(data.getPhase3());
			}
			if(isValidPhase(data.getPhase4())){
				phases.add(data.getPhase4());
			}
			if(isValidPhase(data.getPhase5())){
				phases.add(data.getPhase5());
			}
			if(isValidPhase(data.getPhase6())){
				phases.add(data.getPhase6());
			}
			if(isValidPhase(data.getPhase7())){
				phases.add(data.getPhase7());
			}
			if(isValidPhase(data.getPhase8())){
				phases.add(data.getPhase8());
			}
			if(isValidPhase(data.getPhase9())){
				phases.add(data.getPhase9());
			}
			if(isValidPhase(data.getPhase10())){
				phases.add(data.getPhase10());
			}
			
			String username = getUserInSession();
			
			int result = userGoalManager.addOrUpdateSMARTGoal(username, data.getUserGoal(), phases);
			GoalDTO goal = goalManager.getGoalByTitle(data.getUserGoal().getTitle());
			if(result > 0 && goal != null){	
				request.getSession().removeAttribute("goalTitleAttr");
				return "redirect:/manageSMARTGoal.html?goalId="+goal.getId();
			}
			else{
				return "redirect:/addSMARTGoal.html?goalTitle=" + data.getUserGoal().getTitle();
			}
		}
		
		return null;
	}
	
	boolean isValidPhase(UserGoalPhaseDTO phase){
		return phase != null && !StringUtils.isBlank(phase.getPhaseName()) 
				&& !StringUtils.isBlank(phase.getDeadLine()) && phase.getPercentMeasure() > 0;
	}

	public void initTopPage(BaseModel model, HttpServletRequest request) {
		UserDTO user = getUserSession();
		initTopZone(user, model);
		model.setUserId(user.getId());
	}

	public void initRightPage(BaseModel model, HttpServletRequest request) {
		UserDTO user = getUserSession();
		initRightZone(user, model);
		initPeopleYouMayKnow(user, model);
	}
	
	/**
	 * For add smart goal only
	 */
	public void initLeftPage(BaseModel baseModel, HttpServletRequest request) {		
		Object goalTitleAttr = request.getSession().getAttribute("goalTitleAttr");
		String goalTitle = goalTitleAttr != null ? goalTitleAttr.toString() : "";
		Long goalId = ConvertUtils.toLong(request.getParameter("goalId"), -1L);
		String type = request.getParameter("type");
		SMARTGoalModel model = new SMARTGoalModel();
		model = (SMARTGoalModel) baseModel;
		
		if(goalId > 0L){
			if(!"new".equals(type)){
				request.getSession().removeAttribute("goalTitleAttr");
				initEditSMARTGoal(model, goalId);
			}else{
				GoalDTO goal = goalManager.getGoalByPrimaryKey(goalId);
				initNewSMARTGoal(model, goal.getTitle());
			}
		}else {
			initNewSMARTGoal(model, goalTitle);
		}		
	}
	
	public void initNewSMARTGoal(SMARTGoalModel model, String goalTitle){
		UserGoalDTO userGoal = model.getUserGoal();	
		userGoal.setTitle(goalTitle);
		model.setNewGoalTitle(goalTitle);
		
		UserDTO user = getUserSession();
		model.getSettings().setAllowAddGoal(userGoalManager.allowCreateNewGoal(user));
	}
	
	public void initEditSMARTGoal(SMARTGoalModel model, Long goalId){
		initManageSMARTGoal(goalId, model, null);
		model.setNewGoalTitle(model.getGoalTitle());
	}	

	public void initManageSMARTGoal(Long goalId, SMARTGoalModel model, HttpServletRequest request){
		UserDTO user = getUserSession();
		Long userId = user.getId();
		
		UserGoalDTO userGoal = userGoalManager.getUserGoalByPrimaryKey(userId, goalId);
		List<UserGoalPhaseDTO> phases = userGoalManager.getPhaseList(user.getUsername(), goalId);
		initPhaseList(phases, model);
		model.setUserGoal(userGoal);
		
		model.getSettings().setAllowAddGoal(userGoalManager.allowCreateNewGoal(user));
	}
	
	public void initPhaseList(List<UserGoalPhaseDTO> phases, SMARTGoalModel model){
		String phaseSetterPrefix = "phase";
		for(UserGoalPhaseDTO phase : phases){			
			int index = phase.getIndex().intValue();
			String phaseSetter = phaseSetterPrefix + index;
			try{
				BeanWrapper bw = new BeanWrapperImpl(model);
				bw.setPropertyValue(phaseSetter, phase);
			}catch (BeansException e) {
				logger.error(e);
			}
		}
		
		model.setPhases(phases);
	}
}